home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sysdeps / m88k / m88100 / mul_1.S < prev    next >
Text File  |  1994-01-15  |  4KB  |  128 lines

  1. ; mc88100 __mpn_mul_1 -- Multiply a limb vector with a single limb and
  2. ; store the product in a second limb vector.
  3.  
  4. ; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
  5.  
  6. ; This file is part of the GNU MP Library.
  7.  
  8. ; The GNU MP Library is free software; you can redistribute it and/or modify
  9. ; it under the terms of the GNU General Public License as published by
  10. ; the Free Software Foundation; either version 2, or (at your option)
  11. ; any later version.
  12.  
  13. ; The GNU MP Library is distributed in the hope that it will be useful,
  14. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ; GNU General Public License for more details.
  17.  
  18. ; You should have received a copy of the GNU General Public License
  19. ; along with the GNU MP Library; see the file COPYING.  If not, write to
  20. ; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.  
  23. ; INPUT PARAMETERS
  24. ; res_ptr    r2
  25. ; s1_ptr    r3
  26. ; size        r4
  27. ; s2_limb    r5
  28.  
  29. ; Common overhead is about 11 cycles/invocation.
  30.  
  31. ; The speed for S2_LIMB >= 0x10000 is approximately 21 cycles/limb.  (The
  32. ; pipeline stalls 2 cycles due to WB contention.)
  33.  
  34. ; The speed for S2_LIMB < 0x10000 is approximately 16 cycles/limb.  (The
  35. ; pipeline stalls 2 cycles due to WB contention and 1 cycle due to latency.)
  36.  
  37. ; To enhance speed:
  38. ; 1. Unroll main loop 4-8 times.
  39. ; 2. Schedule code to avoid WB contention.  It might be tempting to move the
  40. ;    ld instruction in the loops down to save 2 cycles (less WB contention),
  41. ;    but that looses because the ultimate value will be read from outside
  42. ;    the allocated space.  But if we handle the ultimate multiplication in
  43. ;    the tail, we can do this.
  44. ; 3. Make the multiplication with less instructions.  I think the code for
  45. ;    (S2_LIMB >= 0x10000) is not minimal.
  46. ; With these techniques the (S2_LIMB >= 0x10000) case would run in 17 or
  47. ; less cycles/limb; the (S2_LIMB < 0x10000) case would run in 11
  48. ; cycles/limb.  (Assuming infinite unrolling.)
  49.  
  50. #include "sysdep.h"
  51.  
  52. ENTRY (__mpn_mul_1)
  53.  
  54.     ; Make S1_PTR and RES_PTR point at the end of their blocks
  55.     ; and negate SIZE.
  56.     lda     r3,r3[r4]
  57.     lda     r6,r2[r4]        ; RES_PTR in r6 since r2 is retval
  58.     subu     r4,r0,r4
  59.  
  60.     addu.co     r2,r0,r0        ; r2 = cy = 0
  61.     ld     r9,r3[r4]
  62.     mask     r7,r5,0xffff        ; r7 = lo(S2_LIMB)
  63.     extu     r8,r5,16        ; r8 = hi(S2_LIMB)
  64.     bcnd.n     eq0,r8,Lsmall        ; jump if (hi(S2_LIMB) == 0)
  65.      subu     r6,r6,4
  66.  
  67. ; General code for any value of S2_LIMB.
  68.  
  69.     ; Make a stack frame and save r25 and r26
  70.     subu     r31,r31,16
  71.     st.d     r25,r31,8
  72.  
  73.     ; Enter the loop in the middle
  74.     br.n    L1
  75.     addu     r4,r4,1
  76.  
  77. Loop:
  78.     ld     r9,r3[r4]
  79.     st     r26,r6[r4]
  80. ; bcnd    ne0,r0,0            ; bubble
  81.     addu     r4,r4,1
  82. L1:    mul     r26,r9,r5        ; low word of product    mul_1    WB ld
  83.     mask     r12,r9,0xffff        ; r12 = lo(s1_limb)    mask_1
  84.     mul     r11,r12,r7        ; r11 =  prod_0        mul_2    WB mask_1
  85.     mul     r10,r12,r8        ; r10 = prod_1a        mul_3
  86.     extu     r13,r9,16        ; r13 = hi(s1_limb)    extu_1    WB mul_1
  87.     mul     r12,r13,r7        ; r12 = prod_1b        mul_4    WB extu_1
  88.     mul     r25,r13,r8        ; r25  = prod_2        mul_5    WB mul_2
  89.     extu     r11,r11,16        ; r11 = hi(prod_0)    extu_2    WB mul_3
  90.     addu     r10,r10,r11        ;            addu_1    WB extu_2
  91. ; bcnd    ne0,r0,0            ; bubble            WB addu_1
  92.     addu.co     r10,r10,r12        ;                WB mul_4
  93.     mask.u     r10,r10,0xffff        ; move the 16 most significant bits...
  94.     addu.ci     r10,r10,r0        ; ...to the low half of the word...
  95.     rot     r10,r10,16        ; ...and put carry in pos 16.
  96.     addu.co     r26,r26,r2        ; add old carry limb
  97.     bcnd.n     ne0,r4,Loop
  98.      addu.ci r2,r25,r10        ; compute new carry limb
  99.  
  100.     st     r26,r6[r4]
  101.     ld.d     r25,r31,8
  102.     jmp.n     r1
  103.      addu     r31,r31,16
  104.  
  105. ; Fast code for S2_LIMB < 0x10000
  106. Lsmall:
  107.     ; Enter the loop in the middle
  108.     br.n    SL1
  109.     addu     r4,r4,1
  110.  
  111. SLoop:
  112.     ld     r9,r3[r4]        ;
  113.     st     r8,r6[r4]        ;
  114.     addu     r4,r4,1        ;
  115. SL1:    mul     r8,r9,r5        ; low word of product
  116.     mask     r12,r9,0xffff        ; r12 = lo(s1_limb)
  117.     extu     r13,r9,16        ; r13 = hi(s1_limb)
  118.     mul     r11,r12,r7        ; r11 =  prod_0
  119.     mul     r12,r13,r7        ; r12 = prod_1b
  120.     addu.cio r8,r8,r2        ; add old carry limb
  121.     extu     r10,r11,16        ; r11 = hi(prod_0)
  122.     addu     r10,r10,r12        ;
  123.     bcnd.n     ne0,r4,SLoop
  124.     extu     r2,r10,16        ; r2 = new carry limb
  125.  
  126.     jmp.n     r1
  127.     st     r8,r6[r4]
  128.